package spring.cloud.tasks.client.batch_task_processor;

import lombok.Getter;
import lombok.Setter;
import spring.cloud.tasks.common.utils.Schedules;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class TaskInfo {
    public final ConcurrentHashMap<String, TaskWorkerInstanceContext> taskInstanceIdToWorkerTaskBatchInfoMap = new ConcurrentHashMap<String, TaskWorkerInstanceContext>();
    @Setter
    @Getter
    private String taskId;
    @Setter
    @Getter
    private volatile boolean stop;

    public void stop() {
        stop = true;
        //
        //线程主动通知+以引用不存在的方式通知底层的线程自我关闭。
        List<TaskWorkerInstanceContext> taskWorkerInstanceContextList = new ArrayList<TaskWorkerInstanceContext>();
        List<String> threadIdList = new ArrayList<String>();
        taskWorkerInstanceContextList.addAll(taskInstanceIdToWorkerTaskBatchInfoMap.values());
        taskInstanceIdToWorkerTaskBatchInfoMap.clear();
        for (TaskWorkerInstanceContext taskWorkerInstanceContext : taskWorkerInstanceContextList) {
            collectThreadId(taskWorkerInstanceContext, threadIdList);
        }
        notifyThreadStop(threadIdList);
    }

    public void stop(String taskInstanceId) {
        //线程主动通知+以引用不存在的方式通知底层的线程自我关闭。
        TaskWorkerInstanceContext taskWorkerInstanceContext = taskInstanceIdToWorkerTaskBatchInfoMap.remove(taskInstanceId);
        List<String> threadIdList = new ArrayList<String>();
        if (taskWorkerInstanceContext != null) {
            collectThreadId(taskWorkerInstanceContext, threadIdList);
        }
        notifyThreadStop(threadIdList);
    }


    /**
     * 除开之外的都需要被清理
     *
     * @param taskInstanceIdList
     */
    public void stop(List<String> taskInstanceIdList) {
        List<TaskWorkerInstanceContext> taskWorkerInstanceContextList = new ArrayList<TaskWorkerInstanceContext>();
        List<String> threadIdList = new ArrayList<String>();
        for (String taskInstanceId : taskInstanceIdToWorkerTaskBatchInfoMap.keySet()) {
            if (!taskInstanceIdList.contains(taskInstanceId)) {
                //线程主动通知+以引用不存在的方式通知底层的线程自我关闭。
                TaskWorkerInstanceContext taskWorkerInstanceContext = taskInstanceIdToWorkerTaskBatchInfoMap.remove(taskInstanceId);//需要考虑批量任务线程是否会陷入死循环的问题。
                taskWorkerInstanceContextList.add(taskWorkerInstanceContext);
            }
        }
        for (TaskWorkerInstanceContext taskWorkerInstanceContext : taskWorkerInstanceContextList) {
            collectThreadId(taskWorkerInstanceContext, threadIdList);
        }
        notifyThreadStop(threadIdList);
    }


    private void collectThreadId(TaskWorkerInstanceContext taskWorkerInstanceContext, List<String> threadIdList) {
        if (taskWorkerInstanceContext == null) {
            return;
        }
        TaskWorkerInstanceClientInfo taskWorkerInstanceClientInfo = taskWorkerInstanceContext.getTaskWorkerInstanceClientInfo();
        if (taskWorkerInstanceClientInfo != null) {
            TaskWorkerInstanceClientInfo.TaskThreadInfo taskCreaterThreadInfo = taskWorkerInstanceClientInfo.getTaskCreaterThreadInfo();
            List<TaskWorkerInstanceClientInfo.TaskThreadInfo> taskExecuterThreadInfoList = taskWorkerInstanceClientInfo.getTaskExecuterThreadInfoList();
            TaskWorkerInstanceClientInfo.TaskThreadInfo taskResultCollecterThreadInfo = taskWorkerInstanceClientInfo.getTaskResultCollecterThreadInfo();
            if (taskCreaterThreadInfo != null) {
                {
                    String threadId = taskCreaterThreadInfo.getThreadId();
                    if (threadId != null) {
                        threadIdList.add(threadId);
                    }
                }
            }
            for (TaskWorkerInstanceClientInfo.TaskThreadInfo taskThreadInfo : taskExecuterThreadInfoList) {
                {
                    String threadId = taskThreadInfo.getThreadId();
                    if (threadId != null) {
                        threadIdList.add(threadId);
                    }
                }
            }
            if (taskResultCollecterThreadInfo != null) {
                {
                    String threadId = taskResultCollecterThreadInfo.getThreadId();
                    if (threadId != null) {
                        threadIdList.add(threadId);
                    }
                }
            }
        }
    }

    private void notifyThreadStop(List<String> threadIdList) {
        for (String threadId : threadIdList) {
            try {
                Thread thread = Schedules.getThreadByThreadName(threadId);
                if (thread != null) {
                    TaskInstanceExecuterThread taskInstanceExecuterThread = (TaskInstanceExecuterThread) thread;
                    taskInstanceExecuterThread.setStopFlag();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
